package com.demo.search;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.TermVector;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.search.highlight.TokenSources;
import org.apache.lucene.search.vectorhighlight.BaseFragmentsBuilder;
import org.apache.lucene.search.vectorhighlight.FastVectorHighlighter;
import org.apache.lucene.search.vectorhighlight.FieldQuery;
import org.apache.lucene.search.vectorhighlight.FragListBuilder;
import org.apache.lucene.search.vectorhighlight.FragmentsBuilder;
import org.apache.lucene.search.vectorhighlight.ScoreOrderFragmentsBuilder;
import org.apache.lucene.search.vectorhighlight.SimpleFragListBuilder;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;

import com.demo.search.util.LuceneUtils;

/**
 * 语法高亮Demo
 * 使用FastVectorHighlighter对象,效能高于HighLighter 约2.5倍
 * @author ryuu.kk
 *
 */
public class FastVectorHighlighterDemo {

	public static void main(String[] args) throws CorruptIndexException, LockObtainFailedException, IOException, ParseException, InvalidTokenOffsetsException {
		
		
		String a = "a";
		String a1 = new String("a");
		System.out.println(a == a1);
		FastVectorHighlighterDemo demo = new FastVectorHighlighterDemo();
		demo.highlighter();
	}
	
	public void highlighter() throws CorruptIndexException, LockObtainFailedException, IOException, ParseException, InvalidTokenOffsetsException {
		RAMDirectory directory = new RAMDirectory();
		//Directory directory = FSDirectory.open(new File("C:\\development\\lucence\\index"));
		//IndexWriterConfig writerConfig = new IndexWriterConfig(Version.LUCENE_36, new StandardAnalyzer(Version.LUCENE_36));
		//Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);
		Analyzer analyzer = LuceneUtils.createChineseAnalyzer();
		IndexWriterConfig writerConfig = new IndexWriterConfig(Version.LUCENE_36, analyzer);
		IndexWriter writer = new IndexWriter(directory, writerConfig);
		// 建立索引
		Document doc = new Document();
		/* ************************************
		 * Field.Store.YES, Field.Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS
		 * 三者缺一不可,如果缺少任何一个,那么会造成,返回结果null的情况。
		 ************************************** */
		doc.add(new Field("contents", "the cool cat jump over the lazy dog. Java编程语言   计算机 the bad dog run over the lazy dog", Field.Store.YES, Field.Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS));
		writer.addDocument(doc);
		writer.close();
		
		//
		IndexReader indexReader = IndexReader.open(directory);
		
		// 索引快照
		IndexReader newReader = IndexReader.openIfChanged(indexReader);
		if (newReader != null) {
			indexReader.close();
			indexReader = newReader;
		}
		IndexSearcher searcher = new IndexSearcher(indexReader);
		
		System.out.println("\n---------------------  这是一个语法高亮的例子   ---------------------------");
		// 同音词检索kool kat与cool cat读音相同,则cool cat将被检索出
		Query query = new QueryParser(Version.LUCENE_36, "contents", analyzer).parse("lazy dog");//kool kat
		
		//分页查询
        TopScoreDocCollector topCollector = TopScoreDocCollector.create(10, false);
		// Run the query
		searcher.search(query, topCollector);
		
		//TopDocs hits = searcher.search(query, 1);
		int total = topCollector.getTotalHits();  
        ScoreDoc[] scoreDocs = topCollector.topDocs(10).scoreDocs;
        int docID = 0;
		if (scoreDocs != null && scoreDocs.length > 0) {
			docID = scoreDocs[0].doc;
			doc = searcher.doc(docID);
		}
		//int docID = hits.scoreDocs[0].doc;
		//doc = searcher.doc(docID);
		String result = doc.get("contents") ;
		System.out.println("\n检索参数 【lazy dog】  -> 检索结果 【 " + result + "】");
		//设置高亮显示格式
		//SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<strong>", "</strong>");
		/* 语法高亮显示设置 */
		// 使用新语法高亮类
		//Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
		FastVectorHighlighter highlighter = getHightlighter() ;
		FieldQuery fieldQuery = highlighter.getFieldQuery(query);
		// highlighter.setTextFragmenter(new SimpleFragmenter(100)); 
		
		// TokenStream contentTokenStream = analyzer.tokenStream("content", new StringReader(result));
		// TokenStream contentTokenStream = TokenSources.getAnyTokenStream(searcher.getIndexReader(), docID, "contents", analyzer);
		String highLightResult = highlighter.getBestFragment(fieldQuery, searcher.getIndexReader(), docID, "contents", 100);		
		System.out.println("\n检索参数 【lazy dog】  -> FastVectorHighlighter高亮结果 【 " + highLightResult + "】");
		
		searcher.close();
		
	}
	
	private FastVectorHighlighter getHightlighter() {
		// new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
		FragListBuilder fragListBuilder = new SimpleFragListBuilder();
		FragmentsBuilder fragmentBuilder = new ScoreOrderFragmentsBuilder(BaseFragmentsBuilder.COLORED_PRE_TAGS, BaseFragmentsBuilder.COLORED_POST_TAGS);
		
		return new FastVectorHighlighter(true, true, fragListBuilder, fragmentBuilder);
	}
	
	

}
